﻿import D3D.Vertex;
import D3D.Matrix;
import D3D.Style;
class D3D.Polygon
{
	//属性
	private var center : Vertex;
	public var screen : Object;
	public var style : Style;
	private var vertexs : Array;
	private var m : Matrix;
	public var pname : String;
	private var preShowTag : MovieClip;
	private var fixVertex : Vertex;
	/*
	line1 : 1,所有点连成一条线
	line2 : 2, 每两点连成一条线
	face1 : 3, 所有点连成一面
	face2 : 4, 每三个不重用的点连成一个面
	face3 : 5,每三个点连成一个面重用1个点
	face4 : 6,每三个点连成一个面重用2个点
	face5 : 7,每四个不重用的点连成一个面
	face6 : 8,每四个点连成一个面重用1个点
	face7 : 9,每四个点连成一个面重用2个点
	
	*/
	public var defaultDrawType : Number;
	public static var drawType : Object = {
		line1 : 1, line2 : 2, face1 : 3, face2 : 4, face3 : 5, face4 : 6, face5 : 7, face6 : 8, face7 : 9
	}
	private var father : Object;
	private var child : Array;
	public var drawList : Array;
	private var me : Object;
	//构造函数
	public function Polygon (__name : String, _drawType : Number)
	{
		if (__name == undefined)
		{
			say ("未定义Polygon名子");
			return;
		} else
		{
			if (_drawType != undefined)
			{
				defaultDrawType = _drawType;
			}
			if (defaultDrawType > 9 || defaultDrawType == undefined)
			{
				defaultDrawType = 6;
			}
			screen = undefined;
			vertexs = new Array ();
			drawList = new Array ();
			pname = __name;
			center = new Vertex ();
			father = new Object ();
			child = new Array ();
			fixVertex = new Vertex ();
			m = new Matrix ();
			me = this;
		}
	}
	//------------------------------  功能区  --------------------------------
	//////////////////////////////////////////////////////////////////////
	public function addChild (p : Polygon, v : Number) : Boolean
	{
		if (p != undefined)
		{
			for (var i in child)
			{
				if (child [i] == p)
				{
					say ("已经加入了这个子骨关节");
					return true;
				}
			}
			child.push (p);
			p.addFather (this, v);
			return true;
		} else
		{
			say ("子骨关节不正确!");
			return false;
		}
	}
	public function delChild (p : Polygon) : Boolean
	{
		if (p != undefined)
		{
			var childs : Array = new Array ();
			for (var i in child)
			{
				if (child [i] != p)
				{
					childs.push (child [i]);
				} else
				{
					p.delFather ();
				}
			}
			child = childs;
			return true;
		} else
		{
			return false;
		}
	}
	public function addFather (p : Polygon, v : Number) : Boolean
	{
		if (p != undefined)
		{
			father.polygon = p;
			father.vertex = v;
			return true;
		} else
		{
			say ("加入父关节不正确!")
			return false;
		}
	}
	public function delFather ()
	{
		father = new Object ();
	}
	private function getVertexByIndex (indexs : Number) : Vertex
	{
		var rv = me.vertexs [indexs];
		if (indexs != undefined && rv != undefined)
		{
			return rv;
		} else
		{
			trace ("没有找到点");
			return undefined;
		}
	}
	public function Rotation (x, y, z, vv)
	{
		var v : Array = new Array ();
		var i = 0;
		var centerv : Vertex;
	
		//--------------------------------------------------
		if (vv != undefined)
		{
			centerv = vv;
		} else
		{
			if (me.father != undefined && me.father.vertex != undefined)
			{
				var vvv = me.father.polygon.getVertexByIndex (me.father.vertex);
				centerv = vvv;
			} else
			{
				centerv = me.center;
			}
		}
		var matrix : Matrix;
		if (screen != undefined)
		{
			matrix = screen.matrix;
		} else
		{
			matrix = me.m;
		}
		
		while (i < vertexs.length)
		{
			v [i] = vertexs [i].deduct (centerv);
			i ++;
		}
		vertexs = matrix.zRotation (v, x, y, z);
		i = 0;
		while (i < vertexs.length)
		{
			vertexs [i] = ((vertexs [i].plus (centerv)));
			i ++;
		}
		//--------------------------------------------------
		
		me.Draw (preShowTag);
		if (child.length > 0) //子骨转动
		
		{
			RotationChild (x, y, z, centerv);
		}
		if (vv != undefined) //中心点的转动处理
		
		{
			var v2 = me.center.deduct (vv);
			v2 = matrix.zRotation (v2, x, y, z);
			v2 = v2.plus (vv);
		}
	}
	private function RotationChild (x, y, z, vv)
	{
		for (var i in child)
		{
			child [i].Rotation (x, y, z, vv);
		}
	}
	public function Move (x, y, z)
	{
		var matrix : Matrix;
		if (screen != undefined)
		{
			matrix = screen.matrix;
		} else
		{
			matrix = me.m;
		}
		vertexs = matrix.zMove (vertexs, x, y, z);
		var v = new Vertex (x, y, z);
		me.center = me.center.plus (v);
		//me.center.toString();
		me.Draw (preShowTag);
		MoveChild (x, y, z);
	}
	private function MoveChild (x, y, z)
	{
		for (var i in child)
		{
			child [i].Move (x, y, z);
		}
	}
	public function addVertex (vertex) : Boolean
	{
		if (vertex == undefined)
		{
			say ("加入VERTEX类型点出错,数据不能为空.");
			return false;
		} else if (vertex.length > 1)
		{
			var i : Number = 0;
			var b : Boolean;
			while (i < vertex.length)
			{
				b = me.addVertex (vertex [i]);
				if ( ! b)
				{
					say ("加入点(" + vertex [i].toString () + ")时出错!");
				}
				i ++;
			}
			return true;
		} else if (vertex.x != undefined)
		{
			vertexs.push (vertex);
			return true;
		} else
		{
			say ("加入的VERTEX类型不正确");
			return false;
		}
	}
	/**  绘制图形
	*
	* @usage
	* @param   tag  如果没有定义screen 则输入绘制的目标movieClip
	* @param   type 绘制方式 Polygon.drawType类型
	* @return
	*/
	public function Draw (tag : MovieClip, type : Number) : Boolean
	{
		if (tag != undefined)
		{
			me.clears (tag);
			tag.jsq = 0;
			tag.ObjList = new Array ();
			preShowTag = tag;
		} else
		{
			say ("绘制目标错误");
		}
		if (type != undefined && type <= 9)
		{
			defaultDrawType = type;
		}
		if (drawList.length > 0)
		{
			var ii = 0;
			while (ii < drawList.length)
			{
				var nn : Number = 0;
				var templist : Array = new Array ();
				while (nn < drawList [ii].vertexs.length)
				{
					templist.push (vertexs [drawList [ii].vertexs [nn]]);
					nn ++;
				}
				if (drawList [ii].type == undefined)
				{
					drawList [ii].type = defaultDrawType;
				}
				switch (drawList [ii].type)
				{
					case 1 :
					if (tag.getInstanceAtDepth (tag.jsq) == undefined)
					{
						tag.createEmptyMovieClip (me.pname + tag.jsq.toString () , tag.jsq);
					}
					drawLine (tag [(me.pname + tag.jsq.toString ())] , templist, style);
					setDepth (tag [(me.pname + tag.jsq.toString ())] , templist);
					tag.jsq ++;
					break;
					case 2 :
					var i = 0;
					while (i < templist.length)
					{
						if ((i + 1) < templist.length)
						{
							if (tag.getInstanceAtDepth (tag.jsq) == undefined)
							{
								tag.createEmptyMovieClip (me.pname + tag.jsq.toString () , tag.jsq);
							}
							var va : Array = new Array ();
							va.push (templist [i]);
							va.push (templist [ ++ i]);
							drawLine (tag [(me.pname + tag.jsq.toString ())] , va , style);
							setDepth (tag [(me.pname + tag.jsq.toString ())] , va);
							tag.jsq ++;
							i ++;
						} else
						{
							break;
						}
					}
					break;
					case 3 :
					if (tag.getInstanceAtDepth (tag.jsq) == undefined)
					{
						tag.createEmptyMovieClip (me.pname + tag.jsq.toString () , tag.jsq);
					}
					drawFace (tag [(me.pname + tag.jsq.toString ())] , templist, style);
					setDepth (tag [(me.pname + tag.jsq.toString ())] , templist );
					tag.jsq ++;
					break;
					case 4 :
					var i = 0;
					while (i < templist.length)
					{
						if ((i + 2) < templist.length)
						{
							if (tag.getInstanceAtDepth (tag.jsq) == undefined)
							{
								tag.createEmptyMovieClip (me.pname + tag.jsq.toString () , tag.jsq);
							}
							var va : Array = new Array ();
							va.push (templist [i]);
							va.push (templist [ ++ i]);
							va.push (templist [ ++ i]);
							drawFace (tag [(me.pname + tag.jsq.toString ())] , va , style);
							setDepth (tag [(me.pname + tag.jsq.toString ())] , va);
							tag.jsq ++;
							i ++;
						} else
						{
							break;
						}
					}
					break;
					case 5 :
					var i = 0;
					while (i < templist.length)
					{
						if ((i + 2) < templist.length)
						{
							if (tag.getInstanceAtDepth (tag.jsq) == undefined)
							{
								tag.createEmptyMovieClip (me.pname + tag.jsq.toString () , tag.jsq);
							}
							var va : Array = new Array ();
							va.push (templist [i]);
							va.push (templist [ ++ i]);
							va.push (templist [ ++ i]);
							drawFace (tag [(me.pname + tag.jsq.toString ())] , va , style);
							setDepth (tag [(me.pname + tag.jsq.toString ())] , va);
							tag.jsq ++;
						} else
						{
							break;
						}
					}
					break;
					case 6 :
					var i = 0;
					while (i < templist.length)
					{
						if ((i + 2) < templist.length)
						{
							if (tag.getInstanceAtDepth (tag.jsq) == undefined)
							{
								tag.createEmptyMovieClip (me.pname + tag.jsq.toString () , tag.jsq);
							}
							var va : Array = new Array ();
							va.push (templist [i]);
							va.push (templist [ ++ i]);
							va.push (templist [ ++ i]);
							drawFace (tag [(me.pname + tag.jsq.toString ())] , va , style);
							setDepth (tag [(me.pname + tag.jsq.toString ())] , va);
							tag.jsq ++;
							i --;
						} else
						{
							break;
						}
					}
					break;
					case 7 :
					var i = 0;
					while (i < templist.length)
					{
						if ((i + 3) < drawList [ii].vertexs.length)
						{
							if (tag.getInstanceAtDepth (tag.jsq) == undefined)
							{
								tag.createEmptyMovieClip (me.pname + tag.jsq.toString () , tag.jsq);
							}
							var va : Array = new Array ();
							va.push (templist [i]);
							va.push (templist [ ++ i]);
							va.push (templist [ ++ i]);
							va.push (templist [ ++ i]);
							drawFace (tag [(me.pname + tag.jsq.toString ())] , va , style);
							setDepth (tag [(me.pname + tag.jsq.toString ())] , va);
							tag.jsq ++;
							i ++;
						} else
						{
							break;
						}
					}
					break;
					case 8 :
					var i = 0;
					while (i < templist.length)
					{
						if ((i + 3) < templist.length)
						{
							if (tag.getInstanceAtDepth (tag.jsq) == undefined)
							{
								tag.createEmptyMovieClip (me.pname + tag.jsq.toString () , tag.jsq);
							}
							var va : Array = new Array ();
							va.push (templist [i]);
							va.push (templist [ ++ i]);
							va.push (templist [ ++ i]);
							va.push (templist [ ++ i]);
							drawFace (tag [(me.pname + tag.jsq.toString ())] , va , style);
							setDepth (tag [(me.pname + tag.jsq.toString ())] , va);
							tag.jsq ++;
						} else
						{
							break;
						}
					}
					break;
					case 9 :
					var i = 0;
					while (i < templist.length)
					{
						if ((i + 2) < templist.length)
						{
							if (tag.getInstanceAtDepth (tag.jsq) == undefined)
							{
								tag.createEmptyMovieClip (me.pname + tag.jsq.toString () , tag.jsq);
							}
							var va : Array = new Array ();
							va.push (templist [i]);
							va.push (templist [ ++ i]);
							va.push (templist [ ++ i]);
							va.push (templist [ ++ i]);
							drawFace (tag [(me.pname + tag.jsq.toString ())] , va , style);
							setDepth (tag [(me.pname + tag.jsq.toString ())] , va);
							tag.jsq ++;
							i --;
						} else
						{
							break;
						}
					}
					break;
				}
				ii ++;
			}
		} else
		{
			//trace("??????");
			if (type == undefined)
			{
				type = defaultDrawType;
			}
			switch (type)
			{
				case 1 :
				if (tag.getInstanceAtDepth (tag.jsq) == undefined)
				{
					tag.createEmptyMovieClip (me.pname + tag.jsq.toString () , tag.jsq);
					//trace ("          " + tag [(me.pname + tag.jsq.toString ())]);
					
				}
				drawLine (tag [(me.pname + tag.jsq.toString ())] , vertexs, style);
				setDepth (tag [(me.pname + tag.jsq.toString ())] , vertexs);
				tag.jsq ++;
				break;
				case 2 :
				var i = 0;
				while (i < vertexs.length)
				{
					if ((i + 1) < vertexs.length)
					{
						if (tag.getInstanceAtDepth (tag.jsq) == undefined)
						{
							tag.createEmptyMovieClip (me.pname + tag.jsq.toString () , tag.jsq);
						}
						var va : Array = new Array ();
						va.push (vertexs [i]);
						va.push (vertexs [ ++ i ]);
						drawLine (tag [(me.pname + tag.jsq.toString ())] , va , style);
						setDepth (tag [(me.pname + tag.jsq.toString ())] , va);
						tag.jsq ++;
						i ++;
					} else
					{
						break;
					}
				}
				break;
				case 3 :
				if (tag.getInstanceAtDepth (tag.jsq) == undefined)
				{
					tag.createEmptyMovieClip (me.pname + tag.jsq.toString () , tag.jsq);
				}
				drawFace (tag [(me.pname + tag.jsq.toString ())] , vertexs, style);
				setDepth (tag [(me.pname + tag.jsq.toString ())] , vertexs );
				tag.jsq ++;
				break;
				case 4 :
				var i = 0;
				while (i < vertexs.length)
				{
					if ((i + 2) < vertexs.length)
					{
						if (tag.getInstanceAtDepth (tag.jsq) == undefined)
						{
							tag.createEmptyMovieClip (me.pname + tag.jsq.toString () , tag.jsq);
						}
						var va : Array = new Array ();
						va.push (vertexs [i]);
						va.push (vertexs [ ++ i]);
						va.push (vertexs [ ++ i]);
						drawFace (tag [(me.pname + tag.jsq.toString ())] , va , style);
						setDepth (tag [(me.pname + tag.jsq.toString ())] , va);
						tag.jsq ++;
						i ++;
					} else
					{
						break;
					}
				}
				break;
				case 5 :
				var i = 0;
				while (i < vertexs.length)
				{
					if ((i + 2) < vertexs.length)
					{
						if (tag.getInstanceAtDepth (tag.jsq) == undefined)
						{
							tag.createEmptyMovieClip (me.pname + tag.jsq.toString () , tag.jsq);
						}
						var va : Array = new Array ();
						va.push (vertexs [i]);
						va.push (vertexs [ ++ i]);
						va.push (vertexs [ ++ i]);
						drawFace (tag [(me.pname + tag.jsq.toString ())] , va , style);
						setDepth (tag [(me.pname + tag.jsq.toString ())] , va);
						tag.jsq ++;
					} else
					{
						break;
					}
				}
				break;
				case 6 :
				var i = 0;
				while (i < vertexs.length)
				{
					if ((i + 2) < vertexs.length)
					{
						if (tag.getInstanceAtDepth (tag.jsq) == undefined)
						{
							tag.createEmptyMovieClip (me.pname + tag.jsq.toString () , tag.jsq);
						}
						var va : Array = new Array ();
						va.push (vertexs [i]);
						va.push (vertexs [ ++ i]);
						va.push (vertexs [ ++ i]);
						drawFace (tag [(me.pname + tag.jsq.toString ())] , va , style);
						setDepth (tag [(me.pname + tag.jsq.toString ())] , va);
						tag.jsq ++;
						i --;
					} else
					{
						break;
					}
				}
				break;
				case 7 :
				var i = 0;
				while (i < vertexs.length)
				{
					if ((i + 3) < vertexs.length)
					{
						if (tag.getInstanceAtDepth (tag.jsq) == undefined)
						{
							tag.createEmptyMovieClip (me.pname + tag.jsq.toString () , tag.jsq);
						}
						var va : Array = new Array ();
						va.push (vertexs [i]);
						va.push (vertexs [ ++ i]);
						va.push (vertexs [ ++ i]);
						va.push (vertexs [ ++ i]);
						drawFace (tag [(me.pname + tag.jsq.toString ())] , va , style);
						setDepth (tag [(me.pname + tag.jsq.toString ())] , va);
						tag.jsq ++;
						i ++;
					} else
					{
						break;
					}
				}
				break;
				case 8 :
				var i = 0;
				while (i < vertexs.length)
				{
					if ((i + 3) < vertexs.length)
					{
						if (tag.getInstanceAtDepth (tag.jsq) == undefined)
						{
							tag.createEmptyMovieClip (me.pname + tag.jsq.toString () , tag.jsq);
						}
						var va : Array = new Array ();
						va.push (vertexs [i]);
						va.push (vertexs [ ++ i]);
						va.push (vertexs [ ++ i]);
						va.push (vertexs [ ++ i]);
						drawFace (tag [(me.pname + tag.jsq.toString ())] , va , style);
						setDepth (tag [(me.pname + tag.jsq.toString ())] , va);
						tag.jsq ++;
					} else
					{
						break;
					}
				}
				break;
				case 9 :
				var i = 0;
				while (i < vertexs.length)
				{
					if ((i + 2) < vertexs.length)
					{
						if (tag.getInstanceAtDepth (tag.jsq) == undefined)
						{
							tag.createEmptyMovieClip (me.pname + tag.jsq.toString () , tag.jsq);
						}
						var va : Array = new Array ();
						va.push (vertexs [i]);
						va.push (vertexs [ ++ i]);
						va.push (vertexs [ ++ i]);
						va.push (vertexs [ ++ i]);
						drawFace (tag [(me.pname + tag.jsq.toString ())] , va , style);
						setDepth (tag [(me.pname + tag.jsq.toString ())] , va);
						tag.jsq ++;
						i --;
					} else
					{
						break;
					}
				}
				break;
			}
		}
		return true;
	}
	private function setDepth (tag : MovieClip, vertexs)
	{
		//------------深度排序
		//目前只是简单的中心点深度排序
		var z : Number = 0;
		for (var i in vertexs)
		{
			z += vertexs [i].z
		}
		z = z / vertexs.length;
		//-------------------
		var i = 0;
		var a : Array = tag._parent.ObjList;
		var b : Array = new Array ();
		while (i < a.length)
		{
			if (a [i].z >= z)
			{
				break;
			} else
			{
				b.push (a [i]);
			}
			i ++;
		}
		b.push ( 
		{
			tag : tag, z : z
		});
		a [i].tag.swapDepths (tag);
		for (var l = i; l < a.length; l ++)
		{
			i ++;
			a [l].tag.swapDepths (i);
		}
	}
	private function clears (tag)
	{
		tag.clear ();
		for (var i in tag)
		{
			if (typeof (tag [i]) == "movieclip")
			{
				me.clears (tag [i]);
			}
		}
	}
	private function drawFace (tag : MovieClip, vertex : Array, style : Style) : Boolean
	{
		if (vertexs.length < 3)
		{
			say ("数据不正确");
			return false;
		}
		if (style == undefined)
		{
			//trace("un1");
			style = screen.style;
			if (style == undefined)
			{
				//trace("un2");
				style == new Style ();
			}
		}
		//style.toString();
		if (style.lco != undefined)
		{
			tag.lineStyle (style.lth, style.lco , style.lal);
		}
		if (style.fco != undefined)
		{
			tag.beginFill (style.fco , style.fal);
		}
		/////////--
		tag.moveTo (vertex [0].x, vertex [0].y);
		var i : Number = 1;
		while (i < vertex.length)
		{
			tag.lineTo (vertex [i].x, vertex [i].y);
			i ++;
		}
		////////////////////////////////////
		if (style.fco != undefined)
		{
			tag.endFill ();
		}
		return true;
	}
	private function drawLine (tag : MovieClip, vertex : Array, style : Style) : Boolean
	{
		if (vertexs.length < 2)
		{
			say ("数据不正确");
			return false;
		}
		if (style == undefined)
		{
			style = screen.style;
			if (style == undefined)
			{
				style == new Style ();
			}
		}
		if (style.lco != undefined)
		{
			tag.lineStyle (style.lth, style.lco , style.lal);
		}
		/////////--
		tag.moveTo (vertex [0].x, vertex [0].y);
		var i : Number = 1;
		while (i < vertex.length)
		{
			tag.lineTo (vertex [i].x, vertex [i].y);
			i ++;
		}
		////////////////////////////////////
		return true;
	}
	//功能函数
	public function RotationCenter (x, y, z)
	{
		vertexs = me.m.zRotation (vertexs, x, y, z);
		me.center = me.m.zRotation (me.center, x, y, z);
		fixVertex = fixVertex.plus (new Vertex (x, y, z));
		trace("--- fix ---");
		trace(x+" "+y+" "+z)
		fixVertex.toString();
		trace("--- fix ---\r\r");
		
		me.Draw (preShowTag);
	}
	public function MoveCenter (x, y, z)
	{
		vertexs = me.m.zMove (vertexs, x, y, z);
		me.center = me.m.zMove (me.center, x, y, z);
		me.Draw (preShowTag);
	}
	public function toString ()
	{
		trace ("----- " + me.pname + " -----");
		trace ("screen:" + ((screen != undefined) ? "有" : "无"));
		me.style.toString ();
		trace ("以下Vertex:");
		for (var i = 0; i < vertexs.length; i ++)
		{
			vertexs [i].toString ();
		}
		trace ("---------------------------");
	}
	private function say (obj : Object)
	{
		trace ("Polygon:" + obj);
	}
	//get set
	public function get x () : Number
	{
		return center.x;
	}
	public function get y () : Number
	{
		return center.y;
	}
	public function get z () : Number
	{
		return center.z;
	}
	public function set x (v : Number)
	{
		me.Move (v, 0, 0);
		//me.center.x += v;
		
	}
	public function set y (v : Number)
	{
		me.Move (0, v, 0);
		//me.center.y += v;
		
	}
	public function set z (v : Number)
	{
		me.Move (0, 0, v);
		//me.center.z += v;
		
	}
}
